package pjn;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

public class Character {

    private Set<String> names = new TreeSet<String>();
    private Map<String, Set<Integer>> namesOccurenceSentences = new HashMap<String, Set<Integer>>();
    private Integer totalOccurrenceCount = 0;
    private GenderAndNumber gender;

    private Set<Integer> positiveSentences = new HashSet<Integer>();
    private Set<Integer> negativeSentences = new HashSet<Integer>();
    private int evaluation;

    private boolean standsAlone = false;

    public Character(String name) {
        addName(name);
    }

    public void addName(String name) {
        names.add(name);
    }

    public Set<String> getNames() {
        return names;
    }

    public void addNameOccurenceSentence(String name, Integer sentenceNumber) {
        Set<Integer> sentenceNumbers = namesOccurenceSentences.get(name);

        if (sentenceNumbers == null) {
            sentenceNumbers = new TreeSet<Integer>();
            namesOccurenceSentences.put(name, sentenceNumbers);
        }
        sentenceNumbers.add(sentenceNumber);

        totalOccurrenceCount += 1;
    }

    public void addNameOccurenceSentences(String name, Set<Integer> numbers) {
        Set<Integer> sentenceNumbers = namesOccurenceSentences.get(name);

        if (sentenceNumbers == null) {
            sentenceNumbers = new TreeSet<Integer>();
            namesOccurenceSentences.put(name, sentenceNumbers);
        }
        sentenceNumbers.addAll(numbers);

        totalOccurrenceCount += numbers.size();
    }

    public boolean isItThisCharacter(String proposition) {
        String shorter;
        String longer;

        for (String name : names) {
            if (name.length() < proposition.length()) {
                shorter = name;
                longer = proposition;
            } else {
                shorter = proposition;
                longer = name;
            }

            if (Math.abs(name.length() - proposition.length()) <= 0.7 * shorter.length()) {
                if (longer.startsWith(shorter.substring(0, (int) Math.round(0.7 * shorter.length())))) {
                    return true;
                }
            }
        }

        return false;
    }

    private void refreshEvaluation() {
        double positiveCount = positiveSentences.size();
        double negativeCount = negativeSentences.size();
        evaluation = (int) ((positiveCount - negativeCount) / (positiveCount + negativeCount) * 100);
    }

    public void setTotalOccurrenceCount(Integer totalOccurrenceCount) {
        this.totalOccurrenceCount = totalOccurrenceCount;
    }

    public Integer getTotalOccurrenceCount() {
        return totalOccurrenceCount;
    }

    public Map<String, Set<Integer>> getNamesOccurenceSentences() {
        return namesOccurenceSentences;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder("Bohater: ");
        for (String name : names) {
            builder.append(name + " " + namesOccurenceSentences.get(name).size() + ", ");
        }
        builder.append("\nRodzaj: " + gender);
        builder.append("\nOcena: " + evaluation);

        return builder.toString();
    }

    public void setGender(GenderAndNumber gender) {
        this.gender = gender;
    }

    public GenderAndNumber getGender() {
        return gender;
    }

    public Set<Integer> getPositiveSentences() {
        return positiveSentences;
    }

    public void addPositiveSentence(int sentenceNumber) {
        positiveSentences.add(sentenceNumber);
        refreshEvaluation();
    }

    public Set<Integer> getNegativeSentences() {
        return negativeSentences;
    }

    public void addNegativeSentence(int sentenceNumber) {
        negativeSentences.add(sentenceNumber);
        refreshEvaluation();
    }

    public int getEvaluation() {
        return evaluation;
    }

    public void setStandsAlone(boolean standsAlone) {
        this.standsAlone = standsAlone;
    }

    public boolean isStandsAlone() {
        return standsAlone;
    }

}
